package com.qdhh.enrollment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qdhh.enrollment.dto.QuizSubmissionQueryDTO;
import com.qdhh.enrollment.mapper.QuizSubmissionMapper;
import com.qdhh.enrollment.mapper.StudentMapper;
import com.qdhh.enrollment.model.QuizSubmission;
import com.qdhh.enrollment.model.Student;
import com.qdhh.enrollment.service.QuizSubmissionService;
import com.qdhh.enrollment.vo.QuizSubmissionVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class QuizSubmissionServiceImpl extends ServiceImpl<QuizSubmissionMapper, QuizSubmission>
    implements QuizSubmissionService {

    @Autowired
    private StudentMapper studentMapper;
    
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Override
    public int countAttempts(String studentId) {
        if (!StringUtils.hasText(studentId)) {
            return 0;
        }
        return (int) this.count(new LambdaQueryWrapper<QuizSubmission>().eq(QuizSubmission::getStudentId, studentId));
    }

    @Override
    public Optional<QuizSubmission> findLatest(String studentId) {
        if (!StringUtils.hasText(studentId)) {
            return Optional.empty();
        }
        QuizSubmission submission = this.getOne(new LambdaQueryWrapper<QuizSubmission>()
            .eq(QuizSubmission::getStudentId, studentId)
            .orderByDesc(QuizSubmission::getCreatedAt)
            .last("LIMIT 1"));
        return Optional.ofNullable(submission);
    }

    @Override
    public Optional<QuizSubmission> findBest(String studentId) {
        if (!StringUtils.hasText(studentId)) {
            return Optional.empty();
        }
        QuizSubmission submission = this.getOne(new LambdaQueryWrapper<QuizSubmission>()
            .eq(QuizSubmission::getStudentId, studentId)
            .orderByDesc(QuizSubmission::getScore)
            .last("LIMIT 1"));
        return Optional.ofNullable(submission);
    }

    @Override
    public QuizSubmission saveSubmission(QuizSubmission submission) {
        this.save(submission);
        return submission;
    }

    @Override
    public IPage<QuizSubmission> findByStudentId(String studentId, int page, int size) {
        Page<QuizSubmission> p = new Page<>(page, size);
        return this.page(p, new LambdaQueryWrapper<QuizSubmission>()
            .eq(QuizSubmission::getStudentId, studentId)
            .orderByDesc(QuizSubmission::getCreatedAt));
    }
    
    @Override
    public IPage<QuizSubmissionVO> querySubmissions(QuizSubmissionQueryDTO queryDTO) {
        // 构建查询条件
        LambdaQueryWrapper<QuizSubmission> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(QuizSubmission::getDeleted, 0); // 软删除过滤
        
        // 按学生ID筛选
        if (StringUtils.hasText(queryDTO.getStudentId())) {
            queryWrapper.eq(QuizSubmission::getStudentId, queryDTO.getStudentId());
        }
        
        // 按是否通过筛选
        if (queryDTO.getPassed() != null) {
            queryWrapper.eq(QuizSubmission::getPassed, queryDTO.getPassed());
        }
        
        // 按分数筛选
        if (queryDTO.getMinScore() != null) {
            queryWrapper.ge(QuizSubmission::getScore, queryDTO.getMinScore());
        }
        if (queryDTO.getMaxScore() != null) {
            queryWrapper.le(QuizSubmission::getScore, queryDTO.getMaxScore());
        }
        
        // 按提交时间筛选
        if (StringUtils.hasText(queryDTO.getStartTime())) {
            try {
                LocalDateTime startTime = LocalDateTime.parse(queryDTO.getStartTime(), DATE_TIME_FORMATTER);
                queryWrapper.ge(QuizSubmission::getCreatedAt, startTime);
            } catch (Exception ignored) {
                // 如果时间格式不正确，忽略该条件
            }
        }
        if (StringUtils.hasText(queryDTO.getEndTime())) {
            try {
                LocalDateTime endTime = LocalDateTime.parse(queryDTO.getEndTime(), DATE_TIME_FORMATTER);
                queryWrapper.le(QuizSubmission::getCreatedAt, endTime);
            } catch (Exception ignored) {
                // 如果时间格式不正确，忽略该条件
            }
        }
        
        // 按时间倒序排列
        queryWrapper.orderByDesc(QuizSubmission::getCreatedAt);
        
        // 分页查询考试记录
        int page = queryDTO.getPage() != null && queryDTO.getPage() > 0 ? queryDTO.getPage() : 1;
        int pageSize = queryDTO.getSize() != null && queryDTO.getSize() > 0 ? queryDTO.getSize() : 10;
        Page<QuizSubmission> submissionPage = new Page<>(page, pageSize);
        IPage<QuizSubmission> submissionResult = this.page(submissionPage, queryWrapper);
        
        // 如果没有记录，直接返回空结果
        if (submissionResult.getRecords().isEmpty()) {
            Page<QuizSubmissionVO> emptyPage = new Page<>(page, pageSize);
            emptyPage.setTotal(0);
            return emptyPage;
        }
        
        // 获取所有涉及的学生ID
        List<String> studentIds = submissionResult.getRecords().stream()
            .map(QuizSubmission::getStudentId)
            .filter(StringUtils::hasText)
            .distinct()
            .collect(Collectors.toList());
        
        // 查询学生信息
        List<Student> students = studentIds.isEmpty() ? List.of() : 
            studentMapper.selectBatchIds(studentIds);
        
        // 构建学生映射
        Map<String, Student> studentMap = students.stream()
            .collect(Collectors.toMap(Student::getId, student -> student));
        
        // 转换为VO，并应用姓名筛选
        List<QuizSubmissionVO> voList = submissionResult.getRecords().stream()
            .map(submission -> {
                QuizSubmissionVO vo = new QuizSubmissionVO();
                vo.setId(submission.getId());
                vo.setOpenid(submission.getStudentId()); // 使用 studentId 作为 openid（兼容字段）
                vo.setScore(submission.getScore());
                vo.setPassed(submission.getPassed());
                vo.setAttemptNo(submission.getAttemptNo());
                vo.setCreatedAt(submission.getCreatedAt());
                
                // 填充学生信息
                Student student = studentMap.get(submission.getStudentId());
                if (student != null) {
                    vo.setName(student.getNick());
                    vo.setStudentNo(student.getStudentNo());
                }
                
                return vo;
            })
            .filter(vo -> {
                // 如果有姓名筛选条件，则进行过滤
                if (StringUtils.hasText(queryDTO.getName())) {
                    return vo.getName() != null && vo.getName().contains(queryDTO.getName());
                }
                return true;
            })
            .collect(Collectors.toList());
        
        // 构建返回的分页结果
        Page<QuizSubmissionVO> voPage = new Page<>(page, pageSize);
        voPage.setRecords(voList);
        voPage.setTotal(submissionResult.getTotal());
        
        return voPage;
    }
    
    @Override
    public Map<String, Object> getStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        // 查询所有未删除的考试记录
        LambdaQueryWrapper<QuizSubmission> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(QuizSubmission::getDeleted, 0);
        
        List<QuizSubmission> allSubmissions = this.list(queryWrapper);
        
        // 计算统计数据
        long totalRecords = allSubmissions.size();
        long passedCount = allSubmissions.stream()
            .filter(submission -> submission.getPassed() != null && submission.getPassed() == 1)
            .count();
        long failedCount = totalRecords - passedCount;
        
        // 计算平均分
        double averageScore = allSubmissions.stream()
            .filter(submission -> submission.getScore() != null)
            .mapToInt(QuizSubmission::getScore)
            .average()
            .orElse(0.0);
        
        statistics.put("totalRecords", totalRecords);
        statistics.put("passedCount", passedCount);
        statistics.put("failedCount", failedCount);
        statistics.put("averageScore", Math.round(averageScore * 100.0) / 100.0); // 保留两位小数
        
        return statistics;
    }
}
